/**
 * Cordia plugin
 *
 * Copyright (c) 2009 Andrew January (morethannothing.co.uk)
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/mit-license.php
 *
 */

(function($) {
    $.Cordia = function() {
	function createGUID() {
	    // GUID function adapated from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
	    function S4() {
		return ((1 + Math.random()) * 0x10000|0).toString(16).substring(1);
	    }
	    return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
	}

	function getUserId() {
	    var cookiename = 'cordiauserid';

	    var cookieoptions = { }

	    if (!!options.cookieexpires) {
		cookieoptions.expires = options.cookieexpires;
	    } else {
		cookieoptions.expires = 365;
	    }
	    if (!!options.cookiepath) {
		cookieoptions.path = options.cookiepath;
	    }
	    if (!!options.cookiedomain) {
		cookieoptions.domain = options.cookiedomain;
	    }
	    if (!!options.cookiesecure) {
		cookieoptions.secure = options.cookiesecure;
	    }

	    var cookie = $.cookie(cookiename);
	    if (cookie == null) {
		cookie = createGUID();
		$.cookie(cookiename, cookie, cookieoptions);
	    }

	    return cookie;
	}


	var defaults = {
	    posturl: null,
	    useuserid: false,
	    userid: getUserId(),
	    sessionid: createGUID(),
	};
    }

    $.Cordia.getCurrentTimestamp = function() {
	var currentDate = new Date();
	var year = currentDate.getFullYear();
	var month = currentDate.getMonth();
	var day = currentDate.getDay();
	var hours = currentDate.getHours();
	var minutes = currentDate.getMinutes();
	var seconds = currentDate.getSeconds();
	var milliseconds = currentDate.getMilliseconds();

	return year + "-" + month + "-" + day + "T" + hours + ":" + minutes + ":" + seconds + "." + milliseconds;
    }

    $.Cordia.log = function(category, message, options) {
	var options = $.extend($.Cordia.defaults, options);
	$.post(options.posturl, {
		'userid': (options.useuserid ? options.userid : null),
		'sessionid': options.sessionid,
		'timestamp': $.Cordia.getCurrentTimestamp(),
		'category': category,
		'message': message
	});
    }

    $.Cordia.logEvent = function(category, event, data, options) {
	var options = $.extend($.Cordia.defaults, options);
	$.post(options.posturl, {
		'userid': (options.useuserid ? options.userid : null),
		'sessionid': options.sessionid,
		'timestamp': $.Cordia.getCurrentTimestamp(),
		'category': category,
		'event': event,
		'data': data,
	});
    }

    $.fn.monitor = function(category, type, options) {
	var options = $.extend($.Cordia.defaults, options);

	return this.each(function() {
	    // Note: Assumes ID's are unique
	    // Code modified from http://snippets.dzone.com/posts/show/3754
	    function getElementPath(elt) {
		var path = '';
		for (; elt && elt.nodeType == 1; elt = elt.parentNode) {
		    if (!!elt.id) {
			return '#' + elt.id + path;
		    }
		    
		    xname = elt.tagName;
		    index = getElementIndex(elt);
		    if (index > 1) {
			xname += '[' + index + ']';
		    }
		    path = '/' + xname + path;
		}

		return path;	
	    }

	    function getElementIndex(elt) {
		var count = 1;
		for (var sib = elt.previousSibling; sib; sib = sib.previousSibling) {
		    if(sib.nodeType == 1 && sib.tagName == elt.tagName) {
			count += 1;
		    }
		}
		return count;
	    }

	    $(this).bind(type, function(e) {
		function getExtraData(e) {
		    var extraData = '';
		    switch(e.type) {
			case 'change':
			    return { value: e.target.value }
			case 'click':
			case 'dblclick':
			case 'mousedown':
			case 'mouseup':
			    return { button: e.button, pageX: e.pageX, pageY: e.pageY }
			case 'mouseenter':
			case 'mouseleave':
			case 'mousemove':
			case 'mouseout':
			case 'mouseover':
			case 'mouseup':
			    return { pageX: e.pageX, pageY: e.pageY }
			case 'keydown':
			case 'keypress':
			case 'keyup':
			    return { keyCode: e.keyCode, shiftKey: e.shiftKey, ctrlKey: e.ctrlKey, altKey: e.altKey };
		    }
		    return { }
		}

		var event = getElementPath(e.target) + '.' + e.type;
		var data = getExtraData(e);
		if (!!options.getExtraData) {
		    data = $.extend(data, options.getExtraData(e));
		}
		$.Cordia.logEvent(category, event, data, options);
	    });
	});
    };
})(jQuery);

